package com.itheima.sms.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.sms.dto.ConfigDTO;
import com.itheima.sms.entity.ConfigEntity;
import com.itheima.sms.mapper.ConfigMapper;
import com.itheima.sms.model.ServerTopic;
import com.itheima.sms.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 通道配置表
 */
@Service
@Slf4j
public class ConfigServiceImpl extends ServiceImpl<ConfigMapper, ConfigEntity> implements ConfigService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public ConfigEntity getByName(String name) {
        LambdaUpdateWrapper<ConfigEntity> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ConfigEntity::getName, name);
        return this.getOne(wrapper);
    }

    @Override
    public void getNewLevel(ConfigDTO entity) {
        LambdaUpdateWrapper<ConfigEntity> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ConfigEntity::getIsEnable, 1);
        wrapper.eq(ConfigEntity::getIsActive, 1);
        wrapper.orderByDesc(ConfigEntity::getLevel);
        wrapper.last("limit 1");
        ConfigEntity configEntity = this.getOne(wrapper);
        if (configEntity == null) {
            entity.setLevel(1);
        } else {
            entity.setLevel(configEntity.getLevel() + 1);
        }
    }

    /**
     * pd-sms-manage中的save | level | update | delete 方法都会变更通道信息, 然后调用这个方法来更新缓存中通道信息
     * 发送消息, 通知短信发送服务更新缓存中的通道优先级
     */
    @Override
    public void sendUpdateMessage() {
        // 1.获取所有注册到redis中的短信发送服务实例
        Map map = redisTemplate.opsForHash().entries("SERVER_ID_HASH");
        log.info("全部服务: {}", map);
        long current = System.currentTimeMillis();

        for (Object key : map.keySet()) {
            long valueLong = Long.parseLong(map.get(key).toString());

            // 五分钟内报告, 说明短信发送服务状态正常
            if ((current - valueLong) < 1000 * 60 * 5) {
                // 删除redis中缓存的可用值, 因为通道优先级发生变化, redis中缓存的可用通道需要重新加载
                redisTemplate.delete("listForConnect");
                // 发布消息, 会被pd-sms-server监听
                redisTemplate.convertAndSend("TOPIC_HIGH_SERVER",
                        ServerTopic.builder()
                                .option(ServerTopic.INIT_CONNECT)
                                .value(key.toString())
                                .build()
                                .toString());
                log.info("发送消息通知短信发送服务重新构建通道");
                // 只需要有一个服务存活, 发送一次消息即可
                return;
            }
        }
    }
}
